package com.yanqu.road.server.manager.douluodalu.impl;

import com.yanqu.road.entity.activity.douluodalu.DouLuoDaLuUserEvent;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuEventInfo;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuRegionInfo;
import com.yanqu.road.entity.activity.douluodalu.enums.eDouLuoDaLuBuffType;
import com.yanqu.road.entity.activity.douluodalu.enums.eDouLuoDaLuEventType;
import com.yanqu.road.entity.log.cross.LogDouLuoDaLuScoreChange;
import com.yanqu.road.logic.activity.DouLuoDaLuLogic;
import com.yanqu.road.server.manager.douluodalu.*;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public abstract class DouLuoDaLuBaseEventAction implements IDouLuoDaLuUserEventAction {

    CrossDouLuoDaLuContext context;

    DouLuoDaLuEventInfo eventInfo;

    public DouLuoDaLuBaseEventAction(CrossDouLuoDaLuContext context, DouLuoDaLuEventInfo eventInfo) {
        this.context = context;
        this.eventInfo = eventInfo;
    }

    public boolean isSupport(){
        if(context.getUserData().getEvent().getEventType() != eventInfo.getEventType()){
            return false;
        }
        return true;
    }

    @Override
    public DouLuoDaLuEventResult init() {
        return init0();
    }

    @Override
    public DouLuoEventHandleResult handle(int action, byte[] params) {
        DouLuoEventHandleResult result = new DouLuoEventHandleResult();
        if(!isSupport()){
            result.setRet(GameErrorCode.E_DOU_LUO_DA_LU_EVENT_TYPE_ERROR);
            return result;
        }
        try {
            synchronized (context.getActivity()) {

                if (!CrossDouLuoDaLuMgr.hasEvent(context.getUserData().getEvent())) {
                    if(eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue()){
                        result.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NOT_IN_REGION);
                    }else {
                        result.setRet(GameErrorCode.E_DOU_LUO_DA_LU_USER_NOT_EVENT);
                    }
                    return result;
                }

                result = handle0(action, params);

                if (eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue() || eventInfo.getEventType() == eDouLuoDaLuEventType.MonsterEvent.getIntValue()) {
                    if (result.isKill()) {
                        //事件完成统计(事件类型，完成次数)
                        CrossDouLuoDaLuMgr.completeEventCount(context.getUserData(), eventInfo);
                    }
                } else {
                    //事件完成统计(事件类型，完成次数)
                    CrossDouLuoDaLuMgr.completeEventCount(context.getUserData(), eventInfo);
                }

                //积分获得日志
                if(result.getScore() > 0){
                    CrossAutoLogMgr.add(new LogDouLuoDaLuScoreChange(context.getActivityId(), context.getUserId(), context.getActivity().getConfig().SCORE_ITEM_ID_FOREST,
                            1, result.getScore(), result.getAllScore()));
                }

                return result;
            }
        }catch (Exception e){
            CrossDouLuoDaLuMgr.getLogger().error("user {} handle event {} is error", context.getUserId(), eventInfo.getEventId());
            CrossDouLuoDaLuMgr.getLogger().error("", e);
            result.setRet(GameErrorCode.E_GAME_ERROR);
            return result;
        }
    }

    public DouLuoDaLuUserEvent newDouLuoDaLuUserEvent() {
        DouLuoDaLuUserEvent event = new DouLuoDaLuUserEvent();
        event.setEventId(eventInfo.getEventId());
        event.setEventType(eventInfo.getEventType());
        event.setMonsterId(Integer.parseInt(eventInfo.getTargetId()));
        event.setRegionId(context.getUserData().getRegionId());
        event.setAddTime(DateHelper.getCurrentSecond());
        return event;
    }



    abstract DouLuoDaLuEventResult init0();


    abstract DouLuoEventHandleResult handle0(int action, byte[] params);

    public static IDouLuoDaLuUserEventAction createAction(CrossDouLuoDaLuContext context, DouLuoDaLuEventInfo eventInfo){
        if(eventInfo.getEventType() == eDouLuoDaLuEventType.MonsterEvent.getIntValue()){
            return new DouLuoDaLuMonsterFightEventAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue()){
            return new DouLuoDaLuPlayerFightEventAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.MonsterBoxEvent.getIntValue()){
            return new DouLuoDaLuMonsterBoxEventAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.MonsterKingHouseEvent.getIntValue()){
            return new DouLuoDaLuMonsterKingHouseEventAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.ShrekGiftsEvent.getIntValue()){
            return new DouLuoDaLuShrekGiftsEventAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.ForestFair.getIntValue()){
            return new DouLuoDaLuForestFairAction(context, eventInfo);
        } else if(eventInfo.getEventType() == eDouLuoDaLuEventType.BuffEvent.getIntValue()){
            return new DouLuoDaLuBuffEventAction(context, eventInfo);
        }
        return null;
    }

    /**
     * 加积分
     */
    protected void handleScore(DouLuoEventHandleResult handleResult) {
        if(eventInfo.getScore() > 0){
            List<Integer> buffIdList = new ArrayList<>();
            buffIdList.add(eDouLuoDaLuBuffType.SCORE_BUFF.getId());
            buffIdList = CrossDouLuoDaLuMgr.mergeXianCaoAndUse(context.getUserData(), buffIdList);

            DouLuoDaLuRegionInfo regionInfo = context.getActivity().getConfig().getRegionInfo(handleResult.getUserEvent().getRegionId());
            //区域基础分数 * 区域体力消耗
            long addScore = regionInfo.getScoreBase() * regionInfo.getEnergy();
            //事件千分比
            addScore = BigDecimal.valueOf(addScore).multiply(BigDecimal.valueOf(eventInfo.getScore())).divide(BigDecimal.valueOf(1000l), 0, BigDecimal.ROUND_UP).longValue();

            //积分仙草加成
            if(buffIdList.contains(eDouLuoDaLuBuffType.SCORE_BUFF.getId())){
                addScore = DouLuoDaLuLogic.calBuff(addScore, eDouLuoDaLuBuffType.SCORE_BUFF, context.getActivity().getConfig());
                context.getUserData().setScore(addScore + context.getUserData().getScore());
                handleResult.setScore(addScore);
            }else {
                context.getUserData().setScore(addScore + context.getUserData().getScore());
                handleResult.setScore(addScore);
            }
            CrossDouLuoDaLuMgr.changeRank(context.getUserData());
            handleResult.setAllScore(context.getUserData().getScore());
            handleResult.getBuffIdList().addAll(buffIdList);
        }
    }

    /**
     * 是否有道具奖励加成(返回给区服)
     */
    public void hasGoodsRewardBuff(DouLuoEventHandleResult handleResult){
        List<Integer> buffIdList = new ArrayList<>();
        buffIdList.add(eDouLuoDaLuBuffType.GOODS_BUFF.getId());
        buffIdList = CrossDouLuoDaLuMgr.mergeXianCaoAndUse(context.getUserData(), buffIdList);
        handleResult.getBuffIdList().addAll(buffIdList);
    }
}
